/*************/
/* Variables */
/*************/

extern int fe_buffer_max;
extern int file_stack_pos;
extern int include_dirs_pos;
extern int last_sym;
extern int user_files_extra;
extern int user_files_pos;
extern int *buckets;

extern long **symtab;

extern char *current_path;
extern char *fe_buffer;

extern char **name_area;
extern char **user_files;

boolean AnyStatementProfile;
boolean AnyTimeProfile;
boolean OpTrace;
boolean OpTypeCheck;
boolean OpProfileStatement;
boolean OpProfileTime;
boolean OpWarning;
boolean usefp;
boolean use_str_sym;

int bp;
int bp_begin;
int bp_end;
int current_file_no;
int current_source_next;
int esc_chars;
int file_start_sym;
int gline_number;
int include_space;
int line_number;
int new_file;
int string_buffer_size;
int thisline_size;
int token_name;
int token_sym;
int yytext_max;

int char_class[300];

int *thisline;
int *string_buffer;

FILE *current_file;
FILE *file_stack[25];

char id_char[255];
char num_char[255];

char *include_name;
char *yytext;

char **include_dirs;


/************/
/* Routines */
/************/

extern long NewDouble(double);

void lex_gets();


/***********/
/* Defines */
/***********/

#define GETCH \
ch = thisline[bp]; \
bp++; \

/* Capture a valid identifier for a variable, function, procedure,
   or type. This pushes bp along so that bp_end can be set after.
   Afterwards, new_sym is called so that the entire identifier can
   be copied from thisline into an appropriately sized buffer. */
#define PUSH_VALID_IDENTIFIER \
ch = thisline[bp]; \
bp++; \
while (id_char[ch]) { \
    ch = thisline[bp]; \
    bp++; \
}

/* Go past the annoying whitespace. */
#define SKIP_WHITESPACE \
ch = thisline[bp]; \
bp++; \
while (ch == ' ' || ch == '\t') { \
    ch = thisline[bp]; \
    bp++; \
}

#define N_BAD_NUMBER 0
#define N_NORMAL_NUMBER 1
#define N_STOP_CHAR 2
#define N_DOT 3
#define N_EXPONENT 4
#define N_MINUS 5
#define N_PLUS 6

#define NEST_MAX 25

struct fe_file_info {
    boolean profile_statement;
    boolean profile_time;
    boolean trace;
    boolean type_check;
    boolean warning;
    char *fname;
    FILE *fptr;
    int line_no;
    int file_start_sym;
};

struct fe_file_info nest_stack[NEST_MAX];
int nest_stack_current;

